﻿package 
{
	import DataTable.CGameDataTable;
	
	import Effect.CEffectManager;
	
	import GameEvent.CGameEvent;
	import GameEvent.CGameEvent_EndShowTime;
	import GameEvent.CGameEvent_SnakeEatSomthing;
	
	import Interface.CGameStateUI_Play;
	
	import Item.CItemManager;
	
	import Map.CMap;
	
	import Snake.CSnake;
	
	import flash.events.KeyboardEvent;
	import flash.events.TimerEvent;
	import flash.ui.Keyboard;
	import flash.utils.Timer;
	
	public class CGameState_Play extends CGameState
	{
		private const COUNT_SNAKEPIECE_TO_DEATH		:uint = 1;
		
		private var m_Map :CMap;
		private var m_Snake :CSnake;
		private var m_ItemManager :CItemManager;
		private var m_CollisionManager :CCollisionManager;
		private var m_EffectManager :CEffectManager;
		private var m_GameDataTable :CGameDataTable;
		
		private var m_GameStateUI :CGameStateUI_Play;
		
		private var m_timer :Timer = new Timer(100);
		
		public function CGameState_Play(refGame :CGame)
		{
			super(refGame);
			
			cMovieClip = new CMC_GameState_Play();
			
			m_Map = new CMap();
			m_Snake = new CSnake(m_Map);
			m_ItemManager = new CItemManager(m_Map);
			m_EffectManager = new CEffectManager();
			m_CollisionManager = new CCollisionManager(m_Snake, m_ItemManager);
			m_GameDataTable = new CGameDataTable();
			
			m_GameStateUI = new CGameStateUI_Play(cMovieClip);
		}
		override public function EnterState() :void
		{
			cMovieClip.addChild(m_Map.sprite);
			cMovieClip.addChild(m_Snake.sprite);
			cMovieClip.addChild(m_ItemManager.sprite);
			cMovieClip.addChild(m_EffectManager.sprite);
			
			CGameStageManager.instance.LoadMapScript();
			m_Map.Init(CGameStageManager.instance.refMapData);
			m_Snake.Init();
			var nTime :Number = m_GameDataTable.GetTimeByFactoryLevel(CGameScoreManager.instance.nCreamPuffFactoryLevel);
			if (nTime == 0)
			{
				trace("Error! CGameState_Play:EnterState(), nTimeToCreateItem_Food is Zero!");
				return;
			}
			m_ItemManager.SetTimeToCreateItem_Food(nTime);
			
			CGameScoreManager.instance.SetMungLength(m_Snake.nBodyPieceCount-1);
			m_GameStateUI.UpdateUI_Score();
			m_GameStateUI.UpdateUI_MungLength(CGameScoreManager.instance.nMungLength,
												CGameScoreManager.instance.nHighestMungLength);
			m_GameStateUI.UpdateUI_EatedFoodCount();
			m_GameStateUI.UpdateUI_Gold();
			m_GameStateUI.UpdateUI_CPFLv();
			var nGoldForUpgrade :uint = m_GameDataTable.GetGoldForUpgrade(CGameScoreManager.instance.nCreamPuffFactoryLevel);
			m_GameStateUI.UpdateUI_GoldToUpgradeCPF(nGoldForUpgrade);
			
			cMovieClip.addEventListener(CGameEvent.EVENT_SNAKE_EAT_SOMETHING, OnSnakeEatSomething);
			cMovieClip.addEventListener(CGameEvent.EVENT_END_SHOWTIME, OnEndShowTime);
			cMovieClip.stage.addEventListener(KeyboardEvent.KEY_DOWN, OnKeyDown);
			
			m_timer.start();
			m_timer.addEventListener(TimerEvent.TIMER, OnTimer);
		}
		override public function LeaveState() :void
		{
			m_timer.stop();
			m_timer.removeEventListener(TimerEvent.TIMER, OnTimer);
			
			cMovieClip.stage.removeEventListener(KeyboardEvent.KEY_DOWN, OnKeyDown);
			cMovieClip.removeEventListener(CGameEvent.EVENT_END_SHOWTIME, OnEndShowTime);
			cMovieClip.removeEventListener(CGameEvent.EVENT_SNAKE_EAT_SOMETHING, OnSnakeEatSomething);
			
			CGameScoreManager.instance.CalculateStageScore();
			m_ItemManager.Clear();
			m_Snake.Clear();
			m_Map.Clear();
			
			cMovieClip.removeChild(m_EffectManager.sprite);
			cMovieClip.removeChild(m_ItemManager.sprite);
			cMovieClip.removeChild(m_Snake.sprite);
			cMovieClip.removeChild(m_Map.sprite);
		}
		override public function Run(tick :Number) :void
		{
			CGameScoreManager.instance.Update(tick);
			
			m_ItemManager.Update(tick);
			m_Snake.Update(tick);
			
			m_EffectManager.Update(tick);
			
			m_CollisionManager.Update();
		}
		private function UpgradeCreamPuffFactory() :void
		{
			if (CGameScoreManager.instance.nCreamPuffFactoryLevel == CGameScoreManager.MAX_LEVEL_CPF) return;
			
			var bIsUpdateUI :Boolean = false;
			var nGoldForUpgrade :uint = m_GameDataTable.GetGoldForUpgrade(CGameScoreManager.instance.nCreamPuffFactoryLevel);
			
			if (nGoldForUpgrade <= CGameScoreManager.instance.nGold)
			{
				var nTime :Number = m_GameDataTable.GetTimeByFactoryLevel(CGameScoreManager.instance.nCreamPuffFactoryLevel);
				if (nTime == 0)
				{
					trace("Error! CGameState_Play:UpgradeCreamPuffFactory(), nTimeToCreateItem_Food is Zero!");
					return;
				}
				m_ItemManager.SetTimeToCreateItem_Food(nTime);
				
				CGameScoreManager.instance.DecreaseGold(nGoldForUpgrade);
				CGameScoreManager.instance.IncreaseCreamPuffFactoryLevel();
				bIsUpdateUI = true;
				
				CSoundManager.instance.PlaySound(CSoundManager.SOUND_6_UPGRADE);
				m_EffectManager.CreateEffect_CPFUpgrade();
			}
			
			if (bIsUpdateUI == true)
			{
				var nGoldForUpgradeNextLevel :uint = m_GameDataTable.GetGoldForUpgrade(CGameScoreManager.instance.nCreamPuffFactoryLevel);
				m_GameStateUI.UpdateUI_Gold();
				m_GameStateUI.UpdateUI_CPFLv();
				m_GameStateUI.UpdateUI_GoldToUpgradeCPF(nGoldForUpgradeNextLevel);
			}
		}
		private function OnSnakeEatSomething(event :CGameEvent_SnakeEatSomthing) :void
		{
			switch(event.nType)
			{
			case CGameEvent_SnakeEatSomthing.TYPE_ITEM_FOOD:
				CGameScoreManager.instance.SetMungLength(m_Snake.nBodyPieceCount-1);
				CGameScoreManager.instance.IncreaseEatedFood();
				m_GameStateUI.UpdateUI_EatedFoodCount();
				m_GameStateUI.UpdateUI_MungLength(CGameScoreManager.instance.nMungLength,
													CGameScoreManager.instance.nHighestMungLength);
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_BLOCK:
			case CGameEvent_SnakeEatSomthing.TYPE_ITEM_VIRUS:
			case CGameEvent_SnakeEatSomthing.TYPE_DOOR:
			case CGameEvent_SnakeEatSomthing.TYPE_BODY:
				CGameScoreManager.instance.SetMungLength(m_Snake.nBodyPieceCount-1);
				m_GameStateUI.UpdateUI_MungLength(CGameScoreManager.instance.nMungLength,
													CGameScoreManager.instance.nHighestMungLength);
				if (m_Snake.nBodyPieceCount <= COUNT_SNAKEPIECE_TO_DEATH)
				{
					CGameScoreManager.instance.bIsSuccess = false;
					m_refGame.EnterState(CGameState.GAME_STATE_RESULT);
				}
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_ITEM_COIN:
				CGameScoreManager.instance.AddGoldFromCoin();
				m_GameStateUI.UpdateUI_Gold();
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_ITEM_GOLD:
				CGameScoreManager.instance.AddGoldFromGold();
				m_GameStateUI.UpdateUI_Gold();
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_GOAL:
				CGameScoreManager.instance.bIsSuccess = true;
				m_refGame.EnterState(CGameState.GAME_STATE_RESULT);
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_ITEM_SHOWTIME:
				m_EffectManager.AddShowTimeEffectToSnake(m_Snake.GetBodyPiece(0).sprite);
				break;
			}
			
			m_GameStateUI.UpdateUI_Score();
			
			switch(event.nType)
			{
			case CGameEvent_SnakeEatSomthing.TYPE_ITEM_FOOD:
				CSoundManager.instance.PlaySound(CSoundManager.SOUND_7_EAT);
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_BLOCK:
				CSoundManager.instance.PlaySound(CSoundManager.SOUND_12_BLOCK);
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_ITEM_VIRUS:
				CSoundManager.instance.PlaySound(CSoundManager.SOUND_11_15_DAMAGE);
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_DOOR:
				CSoundManager.instance.PlaySound(CSoundManager.SOUND_13_KNOCK);
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_ITEM_COIN:
				CSoundManager.instance.PlaySound(CSoundManager.SOUND_8_GETCOIN);
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_ITEM_GOLD:
				CSoundManager.instance.PlaySound(CSoundManager.SOUND_9_GETGOLD);
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_GOAL:
				CSoundManager.instance.PlaySound(CSoundManager.SOUND_14_GOAL);
				break;
			case CGameEvent_SnakeEatSomthing.TYPE_ITEM_SHOWTIME:
				CSoundManager.instance.PlaySound(CSoundManager.SOUND_10_SHOWTIME);
				break;
			}
		}
		private function OnEndShowTime(event :CGameEvent_EndShowTime) :void
		{
			m_EffectManager.RemoveShowTimeEffectToSnake(m_Snake.GetBodyPiece(0).sprite);
		}
		private function OnKeyDown(event :KeyboardEvent) :void
		{
			if (event.keyCode == Keyboard.SPACE)
			{
				UpgradeCreamPuffFactory();
			}
//			else if (event.keyCode == Keyboard.INSERT) /// 개발 버젼 치트키
//			{
//				m_Snake.CheatAction_AddBodyPiece();
//			}
//			else if (event.keyCode == Keyboard.HOME) /// 개발 버젼 치트키
//			{
//				for (var i :uint = 0; i < 100; ++i)
//				{
//					CGameScoreManager.instance.AddGoldFromCoin();
//				}
//				m_GameStateUI.UpdateUI_Gold();
//				UpgradeCreamPuffFactory();
//			}
		}
		private function OnTimer(event :TimerEvent) :void
		{
			m_GameStateUI.UpdateUI_Score();
			m_GameStateUI.UpdateUI_Time(CGameScoreManager.instance.nElapsedTime);
		}
		
	}
}